<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title> 要素的绘制、编辑、GeoJson格式输出</title>
  <meta name="keywords" content=" 要素的绘制、编辑、GeoJson格式输出" />
  <meta name="description" content=" 要素的绘制、编辑、GeoJson格式输出" />
  <link rel="stylesheet" href="{{url('openlayers/resource/bootstrap/css/bootstrap.min.css')}}">
  <script src="{{url('openlayers/resource/bootstrap/js/bootstrap.min.js')}}"></script>
  <script src="{{url('openlayers/resource/axios/axios.min.js')}}"></script>
  <link rel="stylesheet" href="{{url('openlayers/resource/ol/ol.css')}}">
  <script src="{{url('openlayers/resource/ol/ol.js')}}"></script>
  <style>
    html,
    body {
      min-width: 1000px;
    }

    .head {
      height: 50px;
      background-color: #099;
    }

    .layout {
      position: absolute;
      display: flex;
      width: 100%;
      height: 100vh;
    }

    .aside {
      bottom: -5550px;
      width: 350px;
      min-width: 260px;
      height: 100%;
      overflow-y: auto;
    }

    .article {
      min-width: 1000px;
      flex: 1;
      height: 100%;
      overflow-y: auto;
      background-color: #0f9;
    }

    /* 鼠标位置控件层样式设置 */
    #mouse-position {
      float: right;
      position: absolute;
      bottom: 55px;
      /*在地图容器中的层，要设置z-index的值让其显示在地图上层*/
      z-index: 2000;
    }

    /* 鼠标位置信息自定义样式设置 */
    .custom-mouse-position {
      color: rgb(87, 17, 218);
      font-size: 16px;
      font-family: "微软雅黑";
    }

    #menu {
      position: absolute;
      right: 10px;
      top: 10px;
      font-size: 15px;
      z-index: 2000;
    }

    .top-aligned {
      position: absolute;
      top: 10px;
      /* 距离容器顶部10像素 */
      right: 10px;
      /* 距离容器左侧50像素 */
      /* 更多样式如宽度、背景色等 */
      width: 270px;
      background-color: #f0f0f0;
      padding: 10px;
      box-shadow: 0 0 5px #000;
    }

    #layerscontrol {
      position: absolute;
      right: 10px;
      top: 60px;
      font-size: 15px;
      z-index: 2000;
      opacity: 0.9;
    }

    #editmenu {
      position: absolute;
      right: 10px;
      bottom: 160px;
      font-size: 15px;
      z-index: 2000;
    }

    .ol-popup {
      position: absolute;
      background-color: white;
      -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
      filter: drop-shadow(0 1px 4px #FFC125);
      padding: 15px;
      border-radius: 10px;
      border: 1px solid #cccccc;
      bottom: 12px;
      left: -50px;
      min-width: 260px;
    }

    .ol-popup:after,
    .ol-popup:before {
      top: 100%;
      border: solid transparent;
      content: " ";
      height: 0;
      width: 0;
      position: absolute;
      pointer-events: none;
    }

    .ol-popup:after {
      border-top-color: white;
      border-width: 10px;
      left: 48px;
      margin-left: -10px;
    }

    .ol-popup:before {
      border-top-color: #cccccc;
      border-width: 11px;
      left: 48px;
      margin-left: -11px;
    }

    .ol-popup-closer {
      text-decoration: none;
      position: absolute;
      top: 2px;
      right: 8px;
      color: red;
    }

    .ol-popup-closer:after {
      content: "✖";
    }
  </style>
</head>

<body>
  <div class="" style="width: 100%;position: fixed;">
    <div class="head">
      <div style="margin-left: 10px;font-size: 30px; font-weight: 600;color: #ffffff;">要素的绘制、编辑、GeoJson格式输出</div>
    </div>
    <div class="layout">
      <aside class="aside" style="padding: 10px 10px;">
        <div class="input-group mb-3">
          <input type="text" class="form-control" placeholder="档案名、编号">
          <div class="input-group-append">
            <span class="input-group-text" id="basic-addon2" style="cursor: pointer;">搜索</span>
          </div>
        </div>
        <div class="" style="position:sticky; bottom: 55px;">
          <ul class="list-group">
            @foreach($geojsons as $geojson)
            <li class="list-group-item" style="display: flex;justify-content: space-between;align-items:center;">
              <a href="#">{{$geojson->geojson_name}}</a>
              <img src="{{url('openlayers/images/location.png')}}" title="定位到工程点" style="width: 18px; height: 21px;cursor: pointer;"
                onclick="getLayerCenter(map, '{{$geojson->geojson_name}}');">
            </li>
            @endforeach
            <ul>
            <!-- 分页 -->
            <ul class="pagination">
            {{ $geojsons->links() }}
            </ul>
        </div>
      </aside>
      <article class="article">

        <!-- 地图容器 -->
        <div id="map" class="map"></div>

        <!-- 鼠标位置信息 -->
        <div id="mouse-position"></div>

        <!-- 菜单 -->
        <div id="menu">
          <div class="btn-group" data-toggle="buttons">
            <label class="btn btn-secondary opacity-75">
              <input type="checkbox" autocomplete="off" id="layersM" onclick="layersmanger();"> 图层管理
            </label>
            <label class="btn btn-secondary opacity-75" id="restore">复位</label>
          </div>
        </div>

        <!-- 图层编辑 -->
        <div id="editmenu">
          <div class="mb-3">
            <input type="text" class="form-control" id="gongchengid" value="" placeholder="输入工程证号">
          </div>
          <div class="btn-group1" data-toggle="buttons">
            <button type="button" class="btn btn-primary" style="width: 100px;"
              onclick="drawPolygonFeature();">绘制面</button>
            <button type="button" class="btn btn-secondary" style="width: 100px;margin: 0 10px;" id="editbutton"
              onclick="editorFeature();">编辑</button>
            <button type="button" class="btn btn-danger" style=";" onclick="outputJson();">输出GeoJson</button>
          </div>
        </div>

        <!-- 图层管理 -->
        <div id="layerscontrol" style="display: none;">
          <div class="card">
            <h6 class="card-header">图层管理</h6>
            <div class="card-body">
              <div class="" style="display:flex; flex-direction: column;" data-toggle="buttons">
                <div>
                  <label class="btn  opacity-75">
                    <input type="checkbox" checked autocomplete="off" id="luwang" onclick="checkLuWang();"> 路网
                  </label>
                  <input type="range" class="form-range" min="0" max="1" step="0.1" id="lwOpacity" value="1">
                </div>
                <div>
                  <label class="btn opacity-75">
                    <input type="checkbox" autocomplete="off" id="yingXiang" onclick="checkYingXiang()"> 影像
                  </label>
                  <input type="range" class="form-range" min="0" max="1" step="0.1" id="yxOpacity" value="1">
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 弹出图层，跟随经纬度 -->
        <div id="popup" class="ol-popup">
          <a href="#" id="popup-closer" class="ol-popup-closer"></a>
          <div id="popup-content"></div>
          <div id="name" style="font-weight:600;"></div>
          <div id="bianma"></div>
          <div id="dizhi"></div>
          <div id="guishu"></div>
          <div id="wendang"></div>
          <div id="jingdu"></div>
          <div id="weidu"></div>
        </div>

      </article>
    </div>
  </div>

  <script type="text/javascript">  

    /** 创建要添加的图层**/
    // 创建图层：路网
    const MapLayer = new ol.layer.Tile({
      name: 'ml',
      source: new ol.source.XYZ({
        // 设置本地离线瓦片所在路径
        url: '{{url("openlayers/mapabc/roadmap")}}' + '/{z}/{x}/{y}.png',
      })
    });

    // 创建图层：影像
    const YXMapLayer = new ol.layer.Tile({
      source: new ol.source.XYZ({
        // 设置本地离线瓦片所在路径
        url: '{{url("openlayers/mapabc/satellite")}}' + '/{z}/{x}/{y}.jpg',
      })
    });

    /**** 创建地图视图 ****/
    // 把EPSG:4326(经纬度坐标)，转换为EPSG:3857(WGS84网络墨卡托(辅助球))坐标，因为ol默认使用的是EPSG:3857坐标
    let centerPos = ol.proj.transform([117.96, 36.64], 'EPSG:4326', 'EPSG:3857');
    let zoom = 13;
    var view = new ol.View({
      center: centerPos, //地图中心位置
      zoom: zoom, //地图初始层级
      maxZoom: 18,
      minZoom: 1
    })

    const mousePositionControl4326 = new ol.control.MousePosition({
      coordinateFormat: ol.coordinate.createStringXY(4),
      projection: 'EPSG:4326',
      className: 'custom-mouse-position',
      target: document.getElementById('mouse-position'),
    });

    const mousePositionControl3857 = new ol.control.MousePosition({
      coordinateFormat: ol.coordinate.createStringXY(4),
      projection: 'EPSG:3857',
      className: 'custom-mouse-position',
      target: document.getElementById('mouse-position'),
    });

    //创建地图,把地图挂接到容器上
    let map = new ol.Map({
      target: 'map',
      layers: [MapLayer],
      view: view,
      interactions: ol.interaction.defaults.defaults({
        doubleClickZoom: false,   //屏蔽双击放大事件
      }),
      // 显示经纬度控件
      controls: ol.control.defaults.defaults().extend([mousePositionControl4326, mousePositionControl3857]),
    });

    /**** 监听鼠标移动事件 ****/
    map.on('pointermove', function (e) {
      // 鼠标移动到feature区域时变为手形
      var pixel = map.getEventPixel(e.originalEvent);
      var hit = map.hasFeatureAtPixel(pixel);
      map.getTargetElement().style.cursor = hit ? 'pointer' : '';
      // 显示坐标
      // const coordinate = e.coordinate; // 获取当前鼠标位置坐标
    });

    /*** 设置图层的透明度 ***/
    // 设置路网图层的透明度
    document.addEventListener("mousemove", function () {
      // 获取输入框的值
      var lwOpacity = parseFloat(document.getElementById('lwOpacity').value);
      // console.log(lwOpacity); // 输出输入框的值
      MapLayer.setOpacity(lwOpacity);
    });

    // 设置影像图层的透明度
    document.addEventListener("mousemove", function () {
      // 获取输入框的值
      var yxOpacity = parseFloat(document.getElementById('yxOpacity').value);
      // console.log(yxOpacity); // 输出输入框的值
      YXMapLayer.setOpacity(yxOpacity);
    });

    /*****/

    // 矢量图层源
    let vectorSource = new ol.source.Vector({
      wrapX: false
    });

    // 矢量图层
    let vectorLayer = new ol.layer.Vector({
      source: vectorSource,
      zIndex: 1000
    });

    map.addLayer(vectorLayer);

    // 绘制面要素
    function drawPolygonFeature() {
      let draw = new ol.interaction.Draw({
        source: vectorSource,
        type: "Polygon"
      });
      map.addInteraction(draw);
      // 绘制完成
      draw.on("drawend", e => {
        map.removeInteraction(draw);
        draw = null;
      });
    }

    // 编辑要素
    function editorFeature() {
      // 获取按钮元素
      var editButton = document.getElementById('editbutton');
      // 获取按钮的文本内容
      var editText = editButton.textContent || editButton.innerText;
      if (editText == "编辑") {
        console.log(editText);
        editButton.textContent = "完成编辑";
        // 要素选择组件
        var select = new ol.interaction.Select({
          wrapX: false
        });
        // 要素编辑
        var modify = new ol.interaction.Modify({
          features: select.getFeatures()
        });

        // 编辑完成后
        modify.on("modifyend", function (e) {
          console.log("编辑后的要素：", e.features);
        });

        map.addInteraction(select);
        map.addInteraction(modify);
      } else {
        console.log(111);
        editButton.textContent = "编辑";
        map.removeInteraction(select);
        map.removeInteraction(modify);
        select = null;
        modify = null;
      }
    }

    // 输出矢量图层要素为GeoJson数据
    function outputJson() {
      features = vectorSource.getFeatures();
      console.log(features);
      if (features.length == 0) {
        alert('你还没有绘制面要素！');
        return;
      }
      var gongchengid = document.getElementById('gongchengid').value;
      if (features.length == 0) {
        alert('你还没有绘制面要素！');
        return;
      }
      if (gongchengid.trim() == '') {
        alert('请输入工程号！');
        return;
      }
      let jsonObj = new ol.format.GeoJSON().writeFeatures(features, {
        dataProjection: 'EPSG:4326', // 元数据的投影坐标
        featureProjection: 'EPSG:3857', // 规定要素以哪种坐标显示
      });

      console.log("输出GeoJson格式数据：", jsonObj);

      add_geojson(gongchengid, jsonObj);
    }

    // 添加数据到数据库中
    function add_geojson(gongchengid, geojson) {
      axios.post('{{url("api/add_geojson")}}', {
        gongchengid: gongchengid,
        geojson: geojson
      })
        .then(function (response) {
          console.log(response.data);
          if (response.data == 1) {
            alert(gongchengid + ".geojson" + " 文件生成成功！")
          } else {
            alert("生成文件失败，请检查原因！");
          }
        })
        .catch(function (error) {
          console.log(error);
        });
    }

    addAllGeojson();
    // popup();

    // 添加所有geojson文件的要素
    function addAllGeojson()
    {
      // 创建一个空数据源
    var source = new ol.source.Vector({
      wrapX: false
    });

    // 获取geojson文件列表
    axios.get('{{url("api/geojson_list")}}')
      .then((res) => {
        console.log(res.data.length); // 数组的长度
        for(var i = 0; i< res.data.length; i++) {

          console.log(res.data[i].geojson_name); // geojson的文件名字
          var file = res.data[i].geojson_name;

          // geojson数据的源
          let vectorSource = new ol.source.Vector({
            url: '{{url("openlayers/geojson"). "/"}}' + file,
            format: new ol.format.GeoJSON(),
          });

          // 图层的样式
          var styles = new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'blue',
              width: 2,
              opacity: 1
            }),
            fill: new ol.style.Fill({
              color: 'rgba(125, 125, 125, 0.5)',
            }),
            text: new ol.style.Text({
              text: file,
              font: '18px bold serif',
              fill: new ol.style.Fill({
                color: '#fff'
              }),
              stroke: new ol.style.Stroke({
                color: '#000',
                width: 2
              })
            })
          });

          // 设置鼠标经过的时候的图层样式 
          // var hover_styles = new ol.style.Style({
          //   stroke: new ol.style.Stroke({
          //     color: 'blue',
          //     width: 2,
          //     opacity: 1
          //   }),
          //   fill: new ol.style.Fill({
          //     color: 'blue',
          //     opacity: 0.5,
          //   }),
          // });

          // geojson数据的图层
          console.log("====" + file);
          let VectorLayer = new ol.layer.Vector({
            name: file,
            source: vectorSource,
            style: styles,
            zIndex: 200
          });

          map.addLayer(VectorLayer);

          /***** 鼠标经过图层，设置新的样式 *****/
          // let hoverFeature;
          // map.on('pointermove', (e) => {
          //   let features = map.getFeaturesAtPixel(e.pixel)
          //   if (features) {
          //     if (hoverFeature) {
          //       hoverFeature.setStyle(undefined);
          //       hoverFeature = null
          //     }
          //     hoverFeature = features[0];
          //     console.log(hoverFeature);
          //     if(hoverFeature)
          //     {
          //       hoverFeature.setStyle(hover_styles);
          //     }        
          //   }
          //   else {
          //     if (hoverFeature) {
          //       hoverFeature.setStyle(undefined);
          //     }
          //   }
          // });
        }
      })
    }

    // 弹出属性窗口
    function popup()
    {
      /*** 弹出对话框 ***/
      // 获取popup的dom对象
      var container = document.getElementById('popup');
      var content = document.getElementById('popup-content');
      var closer = document.getElementById('popup-closer');

      /***
      ** 隐藏Overlay可使用Overlay.getElement().style.display = 'none'。
      ** 彻底删除Overlay使用Overlay.setMap(null)。
      ***/

      // 创建popup
      var popup = new ol.Overlay({
        element: container, // 指定Overlay使用的DOM元素
        autoPan: true, // 如果弹框不在视口范围内，自动移动地图，让其可见
        positioning: 'bottom-center', // 用于设置弹框相对于传入坐标点的位置
        stopEvent: false, // 是否停止事件传播
        autoPanAnimation: {
          duration: 99
        }
      });
      map.addOverlay(popup);

      // 关闭popup
      closer.onclick = function () {
        popup.setPosition(undefined);
        closer.blur();
        return false;
      };

      // 监听鼠标单击事件，点击feature后弹出popup
      map.on('click', function (e) {
        var coordinate = e.coordinate;
        // console.log("e:" + e);
        // console.log("coordinate:" + coordinate);
        var layer = map.forEachFeatureAtPixel(e.pixel, function(feature, layer) {
          // console.log("feature:" + JSON.stringify(feature));
          return layer;
        });
        if (layer) {
          // 清空html
          // content.innerHTML = '';

          // 城市名称
          // var cityName = document.createElement('h2');
          // cityName.innerText = feature.get('cityName');
          // content.appendChild(cityName);

          // 标题
          var name = document.getElementById('name');
          name.innerText = '地块信息';
          content.appendChild(name);

          // 编码
          var bianma = document.getElementById('bianma');
          bianma.innerText = '编码：' + 'ZC-20240321';
          content.appendChild(bianma);

          // 位置
          var dizhi = document.getElementById('dizhi');
          dizhi.innerText = '地址：' + '淄川区某某地点';
          content.appendChild(dizhi);          

          // 在坐标位置弹出popup
          popup.setPosition(coordinate);
        }
      });
    }

    // 通过图层名字 找到对应图层的中心点
    function getLayerCenter(map, layerName) {
      let center;
      // 通过遍历图层，找到图层的名字
      map.getLayers().forEach(function(layer) {
        if(layer.get('name') === layerName) {
          const source = layer.getSource();
          const extent = source.getExtent();
          center = ol.extent.getCenter(extent);   
        }
      });
      console.log(center); // 图层中心点坐标
      // center = ol.proj.transform(center, 'EPSG:3857', 'EPSG:4326');
      // console.log(center);
      // 定位到中心点
      map.getView().animate({
        center: center,
        duration: 1000,
        zoom: 16,
      })
    }
  </script>
  <script src="{{url('openlayers/resource/olinclude/editfeatures.js')}}"></script>
</body>

</html>